package pinpass;

import java.util.Random;

import org.orm.PersistentException;

import orm.Cliente;

public class PinPass {
	final int nroFilas = 5;
	final int nroColumn = 10;
	private int matriz[][];
	private String tarjeta;
	private String rut;

	private Coordenada c1;
	private Coordenada c2;
	private Coordenada c3;

	/*
	 * Constructor
	 */
	public PinPass(String rut, String passwd) throws PersistentException {
		if (verificar(rut, passwd)) {
			this.rut = rut;
			setTarjeta(rut, passwd);
			setCoordenadasORM();
			// crear 3 coordenadas al azar
			this.c1 = new Coordenada(random(1, 10), random(1, 5));
			this.c2 = new Coordenada(random(1, 10), random(1, 5));
			this.c3 = new Coordenada(random(1, 10), random(1, 5));
		}
	}

	// testing only, remove on environment production!
	@Deprecated
	public String getMatriz() {
		String str = new String();
		for (int i = 0; i < this.nroFilas; i++) {
			for (int j = 0; j < this.nroColumn; j++) {
				str += "\t" + matriz[i][j];
			}
			str += "\n";
		}
		return str;
	}
	public boolean verificar(String rut, String password) throws PersistentException{
		if (new app.Auth().verificarUsuarioPasswd(rut, password))
			return true;
		else
			return false;
		
	}

	/**
	 * Obtiene Coordenadas de tarjeta
	 * 
	 * @return coordenadas del pinpass separados por coma ','
	 */
	public String getCoordenadas() {
		String coord = new String();
		coord = "" + this.c1.toString() + ", ";
		coord += "" + this.c2.toString() + ", ";
		coord += "" + this.c3.toString() + "";
		return coord;
	}

	/**
	 * Verfica Cooordenadas
	 * 
	 * @param valorIngresado
	 *            , array de enteros
	 * @return devuelve true, si coinciden los numeros con los valores de las
	 *         coordenadas, devuelve false en caso contrario
	 */
	public boolean verificarCoordenadas(String coord1, String coord2, String coord3, int[] valorIngresado) {
		int ok = 0;
		
		Coordenada coordenada1 = new Coordenada((char)coord1.toUpperCase().charAt(0), Integer.valueOf(coord1.substring(1)));
		Coordenada coordenada2 = new Coordenada((char)coord2.toUpperCase().charAt(0), Integer.valueOf(coord2.substring(1)));
		Coordenada coordenada3 = new Coordenada((char)coord3.toUpperCase().charAt(0), Integer.valueOf(coord3.substring(1)));
		
		int[] valorCoordenadaTarjeta = getArrayValorCoord(coordenada1, coordenada2, coordenada3);
		for (int i = 0; i < valorCoordenadaTarjeta.length; i++) {
			if (valorCoordenadaTarjeta[i] == valorIngresado[i]) {
				ok++;
			}
		}
		return (ok == 3);
	}

	/**
	 * Obtiene un array de valores de las coordenadas generadas.
	 * 
	 * @return array de valores de las coordenadas
	 */
	@Deprecated
	public int[] getArrayValorCoord() {
		int out[] = new int[3];
		out[0] = this.matriz[this.c1.getCoordenadaY() - 1][this.c1
				.getIntCoordenadaX() - 1];
		out[1] = this.matriz[this.c2.getCoordenadaY() - 1][this.c2
				.getIntCoordenadaX() - 1];
		out[2] = this.matriz[this.c3.getCoordenadaY() - 1][this.c3
				.getIntCoordenadaX() - 1];
		return out;
	}
	public int[] getArrayValorCoord(Coordenada c1, Coordenada c2, Coordenada c3) {
		int out[] = new int[3];		
		out[0] = this.matriz[c1.getCoordenadaY() - 1][c1.getIntCoordenadaX() - 1];
		out[1] = this.matriz[c2.getCoordenadaY() - 1][c2.getIntCoordenadaX() - 1];
		out[2] = this.matriz[c3.getCoordenadaY() - 1][c3.getIntCoordenadaX() - 1];
		return out;
	}
	
	

	/**
	 * Obtiene un array de coordenadas generadas.
	 * 
	 * @return array de String
	 */
	public String[] getArrayCoordenadas() {
		String coord[] = new String[3];
		coord[0] = this.c1.toString();
		coord[1] = this.c2.toString();
		coord[2] = this.c3.toString();
		return coord;
	}

	/**
	 * @param tarjeta  
	 */
	public void setTarjeta(String rut, String passwd)
			throws PersistentException {

		orm.DAOFactory lDAOFactory = orm.DAOFactory.getDAOFactory();
		orm.Tarjeta[] ormTarjetas = lDAOFactory.getTarjetaDAO()
				.listTarjetaByQuery(null, null);
		int length = ormTarjetas.length;
		for (int i = 0; i < length; i++) {
			if (ormTarjetas[i].getCliente_idcliente().getRut().equals(rut))
				this.tarjeta = ormTarjetas[i].getCod();

		}

	}

	/**
	 * @return the tarjeta
	 */
	public String getTarjeta() {
		return tarjeta;
	}

	/**
	 * @return the rut
	 */
	public String getRut() {
		return rut;
	}

	/**
	 * Genera numero entero aleatorio
	 * 
	 * @param limiteInf
	 * @param limiteSup
	 * @return numero entero aleatorio entre ambos limites inclusive.
	 */
	private int random(int limiteInf, int limiteSup) {
		Random r = new Random();
		return (r.nextInt(limiteSup + 1 - limiteInf) + limiteInf);
	}

	/**
	 * Obtiene las coordenadas a partir del orm.
	 * 
	 * @return array de coordenadas
	 * @throws PersistentException
	 */
	private int[] getCoord() throws PersistentException {

		int[] out = new int[nroFilas * nroColumn];

		orm.DAOFactory lDAOFactory = orm.DAOFactory.getDAOFactory();
		Cliente[] ormCliente = lDAOFactory.getClienteDAO().listClienteByQuery(
				"rut='" + this.rut + "'", null);
		orm.Coordenada[] ormCoordenadas = lDAOFactory.getCoordenadaDAO()
				.listCoordenadaByQuery(
						"tarjeta_idtarjeta='"
								+ ormCliente[0].getTarjeta().getIdtarjeta()
								+ "'", null);

		int length = Math.min(ormCoordenadas.length, nroFilas * nroColumn);
		for (int i = 0; i < length; i++) {
			out[i] = ormCoordenadas[i].getValor();
		}
		return out;
	}

	private void setCoordenadasORM() throws PersistentException {
		this.matriz = new int[nroFilas][nroColumn];
		int[] valores = getCoord();
		int k = 0;
		for (int i = 0; i < this.nroFilas; i++) {
			for (int j = 0; j < this.nroColumn; j++) {
				this.matriz[i][j] = valores[k];
				k++;
			}
		}

	}
}
